Floating-point formats are typically defined such that the fraction portion of the number has an assumed 1 (one) to the left of the fractional part (assuming little-endian orientation). Because of this “hidden 1” of the fractional part, the number is able to hold the greatest number of significant bits, thus improving the accuracy of floating-point arithmetic and conversion operations. To maintain the proper normalized value for the fractional part, it is necessary to normalize the results after mathematical operations.
For example, when the number 1.01 is subtracted from 1.011, the resulting 0.001 should be normalized to 1.000, and the exponent part of the number should be adjusted accordingly (decreased by 3). Thus, the normalizing of the fractional part of the number is needed for operations where the leading 0s (zeros) are removed. Normalizing the fractional part is also needed for overflow conditions. For example, when 1.0 is added to 1.0, the result is 2.0. The result should be normalized such that the fractional part is 1.0 (i.e., 0, without the “hidden 1”), and the exponent part should be adjusted accordingly (increased by 1).
Moreover, rounding may be necessary when the precision of a floating-point result is greater than can be represented with the floating-point format. For example, when two numbers are multiplied, the result has twice as many bits of precision as the operands. In such situations, the resulting number may need to be approximated to be represented in the floating-point format. The bits that cannot be represented are used to determine the direction that the number should be rounded (up or down). Floating-to-fixed conversions may also require rounding because only the integer portion of the floating-point operand can be represented in the fixed-point result. The bits that cannot be represented are used to determine the direction that the number should be rounded (up or down).
In performing floating-point arithmetic and conversion operations, additional bits beyond the resulting fractional part must be maintained for rounding purposes. These bits, conventionally called the “guard,” “round” and “sticky” bits, arise from increased precision during the above-described operations, as well as from the addition or subtraction of numbers whose exponent parts are different. For example, if a single-precision floating-point number with an exponent part of 25 is added to a single-precision floating-point number with an exponent part of 0 (zero), the fractional part of the second number must be shifted right with respect to the fractional part of the first number to align the decimal points of the two numbers. However, since single-precision floating-point numbers have only 24 bits of precision, 0 (zero) is added to the fractional part of the first number, and the fractional part of the second number is only used for rounding purposes.
The numerical results of arithmetic operations or format conversions undertaken in a floating-point unit (FPU) often require both normalizing and rounding in order to format the floating-point result in properly (i.e., left justified and with the assumption of a “hidden one”) and to eliminate any spurious or excessive accuracy that may be contained in the results. Typically, the normalization and rounding of the floating-point results require shifting the results either to the left or right, and may require multiple shift operations. Because of the need to shift the results left or right, and because of the need for multiple shift operations, the normalization and rounding of floating-point results may limit the overall frequency of the FPU, or require that one or more additional stages be added to the FPU (i.e., increase the number of clock cycles required for execution). This represents a disadvantage in overall processor performance. Pursuant to the goal of increased processor performance (e.g., speed), it is desirable to decrease the number of logic levels within a given processor stage, and decrease the number of cycles required for execution of each operation.
As processor speeds increase, it is important to minimize the number of logic levels within each stage of the processor. By reducing the number of logic levels, the processor cycle time can be decreased, and lead to higher processor performance. The normalizing and rounding of floating-point unit results affect almost all floating-point arithmetic and conversion instructions. By optimizing these operations, the performance of the floating-point unit can be increased. Accordingly, what is needed in the art is a device and method for decreasing the amount of time (i.e., decreasing the number of logic levels) needed to perform these important floating-point processing steps.